import React, { useEffect, useState } from 'react';
import {
    Button,
    Card,
    Divider,
    Form,
    Icon,
    message,
    Modal,
    Popconfirm,
    Row,
    Select,
    Spin,
    Table,
    Tooltip,
    Typography
} from 'antd';
import { groupBy } from 'lodash';
import classnames from 'classnames';

import BaseSettingProvider from '@/pages/SalaryManage/components/BaseSettingProvider';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import BizIcon from '@/components/BizIcon';
import { isSuccess } from '@/utils/request';
import If from '@/components/If';
import BottomAction from '@/components/BottomAction';
import { numberFormat } from '@/utils/formatterUtil';
import AuthComponent from '@/utils/auth/AuthComponent';

import TwoColHeader from '@/pages/SalaryManage/components/TwoColHead';
import { insuranceHousingFundService } from '@/services/salaryManage/salaryCalculateService';
import {
    housePlaceEnum,
    socialTypeEnum,
    insuranceBaseTypeEnum,
    decimalTypeEnum,
    insuranceFundFileProcessStatus as processStatus
} from '@/pages/SalaryManage/enum';
import {
    goToInsuranceHousingFundLog,
    goToMedicalSocialSecurityAdd,
    goToMedicalSocialSecurityInProcess,
    goToProcessApply,
    goToProcessDetail
} from '@/pages/SalaryManage/utils/pageNavigateUtil';
import { amountSettingColumn, percentSettingColumn } from '@/pages/SalaryManage/utils/TableUtil';
import { getFullNameByCode } from '@/pages/SalaryManage/components/CityCascader';
import EmptyPlaceHolder from '@/pages/SalaryManage/components/EmptyPlaceHolder';
import { PROCESS_TYPE } from '@/pages/SalaryManage/utils/processUtil';
import useHistoryBlock from '@/pages/SalaryManage/hooks/useHistoryBlock';
import { pageTabProps } from '@/pages/SalaryManage/utils';
import salaryStyle from '@/pages/SalaryManage/salaryManage.less';

import { connect } from 'umi';
import { OrganizationNameHead } from '@/pages/SalaryManage/components/OrganizationName';
import MedicalSocialSecurityForm from './components/MedicalSocialSecurityForm';
import ProcessStatusTag from '../components/ProcessStatusTag';
import SocialStatusTag from '../components/SocialStatusTag';

const { Option } = Select;
const { Text } = Typography;

/**
 * 表格列定义
 * @param { Object | null } operateConfig
 * @param { Function } operateConfig.onEdit 点击编辑时的回调
 * @param { Function } operateConfig.onDelete 点击删除时的回调
 * @param { boolean } operateConfig.disabled 是否可操作
 * @returns []
 */
const tableColumn = operateConfig => {
    const rel = [
        {
            title: '户口归属',
            dataIndex: 'housePlace',
            width: 166,
            render: (text, record) => ({
                children: housePlaceEnum.getShowName(text),
                props: {
                    rowSpan: record.v_rowSpan
                }
            })
        },
        {
            title: '险金',
            dataIndex: 'socialType',
            width: 160,
            render: text => socialTypeEnum.getShowName(text)
        },
        {
            title: '基数取值',
            dataIndex: 'baseType',
            width: 160,
            render: text => insuranceBaseTypeEnum.getShowName(text)
        },
        amountSettingColumn({
            title: '最低缴交基数',
            width: 160,
            dataIndex: 'minPayAmt'
        }),
        amountSettingColumn({
            title: '缴交基数',
            width: 160,
            dataIndex: 'basePayAmt'
        }),
        {
            title: '单位',
            dataIndex: '',
            children: [
                percentSettingColumn({
                    title: '比例',
                    dataIndex: 'companyRate'
                }),
                amountSettingColumn({
                    title: '金额',
                    dataIndex: 'companyAmt'
                })
            ]
        },
        {
            title: '个人',
            dataIndex: '比例',
            children: [
                percentSettingColumn({
                    title: '比例',
                    dataIndex: 'personRate'
                }),
                amountSettingColumn({
                    title: '金额',
                    dataIndex: 'personAmt'
                })
            ]
        },
        amountSettingColumn({
            title: '合计',
            dataIndex: 'totalAmt'
        }),
        amountSettingColumn({
            title: '上限',
            dataIndex: 'limitUpperAmt'
        }),
        amountSettingColumn({
            title: '下限',
            dataIndex: 'limitDownAmt'
        }),
        {
            title: '小数位',
            dataIndex: 'roundingType',
            width: 120,
            render: text => decimalTypeEnum.getShowName(text)
        },
        {
            title: '备注',
            dataIndex: 'remark',
            render(text) {
                return (
                    <div style={{ minWidth: 100 }}>
                        <EmptyPlaceHolder value={text} />
                    </div>
                );
            }
        }
    ];

    if (operateConfig) {
        const { onEdit, onDelete, disabled } = operateConfig;

        rel.push({
            title: '操作',
            dataIndex: '',
            width: 100,
            fixed: 'right',
            render(text, record) {
                return (
                    <>
                        <Tooltip title="编辑">
                            <Button
                                className={salaryStyle.operateIcon}
                                onClick={() => onEdit(record)}
                                disabled={disabled}
                            >
                                <BizIcon type="listfunction_edit_icon_default" />
                            </Button>
                        </Tooltip>
                        <Divider type="vertical" />
                        <Popconfirm
                            title="确定要删除吗？"
                            placement="bottomRight"
                            onConfirm={() => onDelete(record)}
                            disabled={disabled}
                        >
                            <Tooltip title="删除" placement="top">
                                <Button className={salaryStyle.operateIcon} disabled={disabled}>
                                    <BizIcon type="DeleteIcon" />
                                </Button>
                            </Tooltip>
                        </Popconfirm>
                    </>
                );
            }
        });
    }

    return rel;
};

const getGroupKey = item => item?.housePlace;

const wrapDataSource = dataList => {
    const allData = [].concat(dataList);
    const dataGroup = groupBy(allData, 'housePlace');

    return allData.map((item, index, arr) => {
        const preItem = index === 0 ? null : arr[index - 1];
        const totalAmt = numberFormat((item.personAmt || 0) + (item.companyAmt || 0), 2, '');

        return {
            ...item,
            totalAmt,
            v_rowSpan: getGroupKey(preItem) !== getGroupKey(item) ? dataGroup[getGroupKey(item)].length : 0
        };
    });
};

const TableWrapper = ({ columns, dataSource }) => {
    const [hoverData, setHoverRowData] = useState(null);

    const tableProps = {
        onRow: record => ({
            className: classnames({
                'row-hover': hoverData && getGroupKey(hoverData) === getGroupKey(record)
            }),
            onMouseEnter: () => {
                setHoverRowData(record);
            },
            onMouseLeave: () => {
                setHoverRowData(null);
            }
        })
    };

    return (
        <div>
            <Table
                columns={columns}
                rowKey="id"
                dataSource={dataSource}
                pagination={false}
                scroll={{ x: 'max-content' }}
                bordered
                {...tableProps}
            />
        </div>
    );
};

/**
 * 编辑模态框
 * @param model
 * @param visible 是否可见
 * @param onOk 确定时的回调
 * @param onCancel 取消时的回调
 * @constructor
 */
const EditModal = Form.create()(({ form, model, visible, onOk, onCancel }) => {
    const [loading, setLoading] = useState(false);

    const onModalOk = () => {
        form.validateFieldsAndScroll((errors, values) => {
            if (errors) {
                return;
            }

            if (values.limitUpperAmt && values.limitDownAmt && values.limitUpperAmt < values.limitDownAmt) {
                message.error('【下限】不能大于【上限】');
                return;
            }

            setLoading(true);
            onOk(
                {
                    ...model,
                    ...values
                },
                setLoading
            );
        });
    };

    return (
        <Modal title="编辑" visible={visible} onOk={onModalOk} onCancel={onCancel}>
            <Spin spinning={loading}>
                <Form layout="horizontal" labelCol={{ span: 6 }} wrapperCol={{ span: 17 }}>
                    <Row style={{ marginBottom: '16px' }}>
                        <Text type="secondary">* 仅支持以下内容进行编辑</Text>
                    </Row>
                </Form>
                <MedicalSocialSecurityForm form={form} model={model} organizationCode={model?.organizationCode} />
            </Spin>
        </Modal>
    );
});

// 已生效
const EFFECT_IN = 0;

/**
 * 增加显示全称
 * @param cityList
 * @returns {*[]}
 */
const wrapCityList = cityList => {
    const rel = [...cityList];

    return rel.map(item => ({
        ...item,
        v_fullName: item.socialCityCode ? getFullNameByCode(item.socialCityCode) : item.socialCityName
    }));
};

const MedicalSocialSecurity = ({ /* organizationCode, */ form, location, history }) => {
    const { organizationCode } = location.query;
    const { getFieldDecorator } = form;

    const [dataSource, setDataSource] = useState([]);
    const [loading, setLoading] = useState(false);
    // 编辑框是否显示
    const [editModalVisible, setEditModalVisible] = useState(false);
    // 正在编辑的行
    const [editingRow, setEditionRow] = useState(null);
    const [cityLoading, setCityLoading] = useState(false);
    const [cityList, setCityList] = useState([]);
    const [selectedCity, setSelectedCity] = useState(null);
    const [approveInfo, setApproveInfo] = useState({});
    const [pageModel, setPageModel] = useState({});
    const [resetVisible, setResetVisible] = useState(false);
    useHistoryBlock(history);

    // 获取查询条件
    const getSearchCondition = () => form.getFieldsValue();

    const effect = location.query.effect ? +location.query.effect : EFFECT_IN;

    // 用来设置默认选择的城市
    const { socialCityCode } = location.query;

    const getPostData = searchCondition => ({
        ...searchCondition,
        effect
    });

    // 查询
    const search = () => {
        const searchCondition = getSearchCondition();

        if (!searchCondition.socialId) {
            return;
        }
        setLoading(true);
        insuranceHousingFundService
            .queryMedicalSocial(getPostData(searchCondition))
            .then(searchResponse => {
                if (isSuccess(searchResponse)) {
                    const model = searchResponse.data;
                    setPageModel(model);
                    const dataSourceList = wrapDataSource(model.data);
                    setDataSource(dataSourceList);
                } else {
                    message.error(searchResponse.msg);
                }
            })
            .finally(() => setLoading(false));
    };

    const cityChange = value => {
        form.setFieldsValue({ socialId: value });
        setSelectedCity(cityList.find(item => item.id === value));
        search();
    };

    // 展开编辑弹出框
    const showEditModal = record => {
        setEditionRow(record);
        setEditModalVisible(true);
    };

    // 点击删除
    const onDelete = record => {
        setLoading(true);
        insuranceHousingFundService
            .deleteMedicalSocial(record.id)
            .then(response => {
                if (!isSuccess(response)) {
                    message.error(response.msg);
                    return;
                }
                message.success('删除成功！');
                search();
            })
            .finally(() => setLoading(false));
    };

    /**
     * 编辑保存时的回调
     * @param {object} newRecord 编辑后的新数据
     * @param {function} setEditModalLoading 设置编辑弹框是否在加载
     */
    const afterEdit = (newRecord, setEditModalLoading) => {
        setLoading(true);
        setEditModalLoading(true);
        insuranceHousingFundService
            .saveEditMedicalSocial(newRecord)
            .then(response => {
                if (!isSuccess(response)) {
                    message.error(response.msg);
                    return;
                }
                message.success('保存成功！');
                search();
                setEditModalVisible(false);
            })
            .finally(() => {
                setEditModalLoading(false);
                setLoading(false);
            });
    };

    // 是否可编辑
    const resetAble = () => !!pageModel?.resetAble;
    // 是否可进入下一步
    const nextAble = () => !!pageModel?.nextAble;

    const reset = () => {
        setResetVisible(true);
    };
    const doReset = () => {
        const searchCondition = getSearchCondition();

        setLoading(true);
        insuranceHousingFundService
            .resetMedicalSocial(searchCondition)
            .then(response => {
                if (!isSuccess(response)) {
                    message.warn(response.msg);
                    return;
                }
                message.success('重置成功！');
                setResetVisible(false);
                search();
            })
            .finally(() => {
                setLoading(false);
            });
    };
    const onNext = async () => {
        const searchCondition = getSearchCondition();
        await goToProcessApply(
            PROCESS_TYPE.SALARY_SET_SOCIAL_APPLY,
            { socialId: searchCondition.socialId, organizationCode },
            '没有找到分类为【财务险金档案流程】的流程，请先配置流程'
        );
    };

    useEffect(() => {
        if (organizationCode) {
            setCityLoading(true);
            // 查询市医社保档案-城市列表
            insuranceHousingFundService
                .querySocialCityList(organizationCode, effect)
                .then(cityResponse => {
                    setCityLoading(false);
                    if (isSuccess(cityResponse)) {
                        setCityList(wrapCityList(cityResponse.data));
                    } else {
                        message.error(cityResponse.msg);
                    }
                })
                .catch(() => {
                    setCityLoading(false);
                });
        }
    }, [organizationCode]);

    useEffect(() => {
        if (cityList?.length > 0) {
            let defaultSelectedCity = socialCityCode && cityList.find(city => city.socialCityCode === socialCityCode);

            defaultSelectedCity = defaultSelectedCity || cityList?.[0];
            setSelectedCity(defaultSelectedCity);
            form.setFieldsValue({ socialId: defaultSelectedCity.id });

            search();
        }
    }, [cityList]);

    useEffect(() => {
        if (selectedCity) {
            // 城市医社保档案-获取审批详情
            insuranceHousingFundService.querySocialApproveInfo({ socialId: selectedCity.id }).then(response => {
                if (isSuccess(response)) {
                    setApproveInfo(response.data);
                }
            });
        }
    }, [selectedCity]);

    return (
        <PageHeaderWrapper type="success">
            <BaseSettingProvider organizationCode={organizationCode}>
                <Card
                    bordered={false}
                    title={
                        <>
                            <span className={salaryStyle.mr8}>险金档案</span>
                            {EFFECT_IN === effect ? (
                                <SocialStatusTag status={pageModel?.socialStatus} />
                            ) : (
                                <>
                                    <ProcessStatusTag status={pageModel?.processStatus} className={salaryStyle.ml8}>
                                        {approveInfo?.year && approveInfo?.month ? (
                                            <>
                                                (
                                                {`${approveInfo.year}-${approveInfo.month < 10 ? '0' : ''}${
                                                    approveInfo.month
                                                }`}
                                                起)
                                            </>
                                        ) : null}
                                    </ProcessStatusTag>
                                </>
                            )}
                        </>
                    }
                    extra={
                        EFFECT_IN === effect ? (
                            <div
                                style={{
                                    display: 'flex',
                                    lineHeight: '31px'
                                }}
                            >
                                <OrganizationNameHead organizationCode={organizationCode} />
                                <Button
                                    onClick={() => goToInsuranceHousingFundLog(organizationCode)}
                                    className={salaryStyle.ml12}
                                >
                                    操作日志
                                </Button>
                            </div>
                        ) : (
                            <OrganizationNameHead organizationCode={organizationCode} />
                        )
                    }
                    {...pageTabProps()}
                >
                    <Spin spinning={loading}>
                        <TwoColHeader
                            left={
                                <Form layout="inline">
                                    <Form.Item label="城市">
                                        {getFieldDecorator('socialId', {
                                            initialValue: selectedCity?.id
                                        })(
                                            <Select
                                                loading={cityLoading}
                                                onChange={cityChange}
                                                dropdownMatchSelectWidth={false}
                                                style={{ width: '180px' }}
                                            >
                                                {cityList.map(city => (
                                                    <Option key={city.id} value={city.id}>
                                                        {city.v_fullName}
                                                    </Option>
                                                ))}
                                            </Select>
                                        )}
                                    </Form.Item>

                                    {EFFECT_IN === effect ? (
                                        <Button
                                            type="primary"
                                            ghost
                                            className={salaryStyle.mr8}
                                            onClick={() => {
                                                goToMedicalSocialSecurityInProcess(
                                                    organizationCode,
                                                    selectedCity?.socialCityCode
                                                );
                                            }}
                                        >
                                            待生效档案
                                        </Button>
                                    ) : null}

                                    <Button
                                        type="primary"
                                        ghost
                                        onClick={() =>
                                            goToProcessDetail({
                                                processDefinitionId: approveInfo?.processDefinitionId,
                                                processInstanceId: approveInfo?.processId
                                            })
                                        }
                                        disabled={!(approveInfo.processDefinitionId && approveInfo.processId)}
                                    >
                                        查看审批详情
                                    </Button>
                                </Form>
                            }
                            right={
                                EFFECT_IN === effect ? (
                                    <AuthComponent code="finance:salary:computation:social:social:add">
                                        <Button
                                            type="primary"
                                            onClick={() =>
                                                goToMedicalSocialSecurityAdd(
                                                    organizationCode,
                                                    selectedCity?.socialCityCode
                                                )
                                            }
                                        >
                                            <Icon type="plus" />
                                            新增
                                        </Button>
                                    </AuthComponent>
                                ) : null
                            }
                            style={{ marginTop: 8 }}
                        />
                        <TableWrapper
                            columns={tableColumn(
                                EFFECT_IN === effect
                                    ? {
                                          onEdit: showEditModal,
                                          onDelete,
                                          disabled: processStatus.APPROVING === selectedCity?.processStatus
                                      }
                                    : null
                            )}
                            dataSource={dataSource}
                            pagination={false}
                        />
                        <If condition={editModalVisible}>
                            <EditModal
                                model={editingRow}
                                visible={editModalVisible}
                                onOk={afterEdit}
                                onCancel={() => setEditModalVisible(false)}
                            />
                        </If>

                        <If condition={EFFECT_IN === effect}>
                            <BottomAction>
                                <Button onClick={reset} disabled={!resetAble()}>
                                    重置
                                </Button>
                                <Button type="primary" onClick={onNext} disabled={!nextAble()}>
                                    下一步
                                </Button>
                            </BottomAction>
                            <Modal
                                visible={resetVisible}
                                title="重置"
                                okText="确定"
                                cancelText="取消"
                                onOk={doReset}
                                onCancel={() => setResetVisible(false)}
                                width={480}
                                centered
                            >
                                <div style={{ margin: '30px 20px' }}>
                                    重置后所有数据将回退到上次审批通过的结果，是否确定重置？
                                </div>
                            </Modal>
                        </If>
                    </Spin>
                </Card>
            </BaseSettingProvider>
        </PageHeaderWrapper>
    );
};
export default connect((state, { location }) => ({
    organizationCode: location?.query?.organizationCode,
    effect: location?.query?.effect
}))(Form.create({})(MedicalSocialSecurity));
